package com.healthyeating.manage.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.healthyeating.common.utils.DateUtils;
import com.healthyeating.common.utils.SecurityUtils;
import com.healthyeating.manage.domain.AssocNutrition;
import com.healthyeating.manage.mapper.AssocNutritionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.healthyeating.manage.mapper.EatMapper;
import com.healthyeating.manage.domain.Eat;
import com.healthyeating.manage.service.IEatService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 进食记录Service业务层处理
 *
 * @author 段奇乐
 * @date 2024-12-18
 */
@Service
public class EatServiceImpl implements IEatService {

    @Autowired
    private EatMapper eatMapper;

    @Autowired
    private AssocNutritionMapper assocNutritionMapper;

    /**
     * 查询进食记录
     *
     * @param eatId 进食记录主键
     * @return 进食记录
     */
    @Override
    public Eat selectEatByEatId(Long eatId) {
        return eatMapper.selectEatByEatId(eatId);
    }

    /**
     * 查询进食记录列表
     *
     * @param eat 进食记录
     * @return 进食记录
     */
    @Override
    public List<Eat> selectEatList(Eat eat) {
        if (eat.getCreateTime() != null) {
            Map<String, Object> map = DateUtils.extractTime(eat.getCreateTime());
            eat.setStartOfDay((Date) map.get("startOfDay"));
            eat.setEndOfDay((Date) map.get("endOfDay"));
        }
        eat.setUserId(SecurityUtils.getUserId());
        return eatMapper.selectEatList(eat);
    }

    /**
     * 新增进食记录
     *
     * @param eatList 进食记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertEat(List<Eat> eatList) {
        List<Eat> insertList = eatList.stream().peek(eat -> {
            eat.setCreateTime(DateUtils.getNowDate());
            eat.setUserId(SecurityUtils.getUserId());
        }).collect(Collectors.toList());
        int result = eatMapper.batchInsertEat(insertList);
        // 对eatList中的对象去重，排除掉相同的eatName
        List<Eat> sortEatList = eatList
                .stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Eat::getEatName))), ArrayList::new));
        List<AssocNutrition> assocNutritionList = new ArrayList<>();
        sortEatList.forEach(eat -> {
            AssocNutrition assocNutrition = new AssocNutrition();
            assocNutrition.setAssocId(eat.getEatId());
            assocNutrition.setSource("tb_eat");
            assocNutrition.setDietName(eat.getEatName());
            assocNutrition.setCreateTime(DateUtils.getNowDate());
            assocNutrition.setUpdateTime(DateUtils.getNowDate());
            assocNutrition.setUpdateBy(SecurityUtils.getUsername());
            assocNutritionList.add(assocNutrition);
        });
        List<AssocNutrition> _assocNutritionList = assocNutritionMapper.selectAssocNutritionList(new AssocNutrition());
        // 查询是否已经存在，如果存在，将重复的部分移除
        List<AssocNutrition> newAssocNutritionList = assocNutritionList.stream()
                .filter(assocNutrition -> {
                    // 检查当前 assocNutrition 是否已经存在于 _assocNutritionList 中
                    return _assocNutritionList.stream()
                            .noneMatch(_assocNutrition -> _assocNutrition.getDietName().equals(assocNutrition.getDietName()));
                })
                .collect(Collectors.toList());
        if (!newAssocNutritionList.isEmpty()) {
            assocNutritionMapper.batchInsertAssocNutrition(newAssocNutritionList);
        }
        return result;
    }

    /**
     * 修改进食记录
     *
     * @param eatList 进食记录
     * @return 结果
     */
    @Override
    @Transactional
    public int updateEat(List<Eat> eatList) {
        // 筛选出没有eatId的数据
        List<Eat> insertEatList = eatList.stream().filter(eat -> eat.getEatId() == null).collect(Collectors.toList());
        // 筛选出有eatId的数据
        List<Eat> updateEatList = eatList.stream().filter(eat -> eat.getEatId() != null).collect(Collectors.toList());
        // 查询当天所有的食物
        Eat eat = new Eat();
        eat.setCreateTime(DateUtils.getNowDate());
        Map<String, Object> map = DateUtils.extractTime(eat.getCreateTime());
        eat.setUserId(SecurityUtils.getUserId());
        eat.setStartOfDay((Date) map.get("startOfDay"));
        eat.setEndOfDay((Date) map.get("endOfDay"));
        List<Eat> eats = eatMapper.selectEatList(eat);
        // 比较updateEatList和eats的大小，如果updateEatList比eats小，删除掉eats中多的一部分
        if (updateEatList.size() < eats.size()) {
            List<Long> eatIds = eats.stream().map(Eat::getEatId).collect(Collectors.toList());
            List<Long> updateEatIds = updateEatList.stream().map(Eat::getEatId).collect(Collectors.toList());
            List<Long> deleteEatIds = eatIds.stream().filter(eatId -> !updateEatIds.contains(eatId)).collect(Collectors.toList());
            eatMapper.deleteEatByEatIds(deleteEatIds.toArray(new Long[0]));
        }
        // 批量新增
        if (!insertEatList.isEmpty()) {
            List<Eat> insertEats = insertEatList.stream().peek(eatItem -> {
                eatItem.setCreateTime(DateUtils.getNowDate());
                eatItem.setUserId(SecurityUtils.getUserId());
            }).collect(Collectors.toList());
            eatMapper.batchInsertEat(insertEats);
            // 对eatList中的对象去重，排除掉相同的eatName
            List<Eat> sortEatList = insertEats
                    .stream()
                    .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Eat::getEatName))), ArrayList::new));
            List<AssocNutrition> assocNutritionList = new ArrayList<>();
            sortEatList.forEach(_eat -> {
                AssocNutrition assocNutrition = new AssocNutrition();
                assocNutrition.setAssocId(_eat.getEatId());
                assocNutrition.setSource("tb_eat");
                assocNutrition.setDietName(_eat.getEatName());
                assocNutrition.setCreateTime(DateUtils.getNowDate());
                assocNutrition.setUpdateTime(DateUtils.getNowDate());
                assocNutrition.setUpdateBy(SecurityUtils.getUsername());
                assocNutritionList.add(assocNutrition);
            });
            List<AssocNutrition> _assocNutritionList = assocNutritionMapper.selectAssocNutritionList(new AssocNutrition());
            // 查询是否已经存在，如果存在，将重复的部分移除
            List<AssocNutrition> newAssocNutritionList = assocNutritionList.stream()
                    .filter(assocNutrition -> _assocNutritionList.stream()
                            .noneMatch(_assocNutrition -> _assocNutrition.getDietName().equals(assocNutrition.getDietName())))
                    .collect(Collectors.toList());
            if (!newAssocNutritionList.isEmpty()) {
                assocNutritionMapper.batchInsertAssocNutrition(newAssocNutritionList);
            }
        }
        return eatMapper.batchUpdateEat(updateEatList);
    }

    /**
     * 批量删除进食记录
     *
     * @param eatIds 需要删除的进食记录主键
     * @return 结果
     */
    @Override
    public int deleteEatByEatIds(Long[] eatIds) {
        return eatMapper.deleteEatByEatIds(eatIds);
    }

    /**
     * 删除进食记录信息
     *
     * @param eatId 进食记录主键
     * @return 结果
     */
    @Override
    public int deleteEatByEatId(Long eatId) {
        return eatMapper.deleteEatByEatId(eatId);
    }
}
